package com.wzdigit.wms.wms.service.inv.count;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wzdigit.framework.Shift;
import com.wzdigit.mes.basic.api.BasicVendorApi;
import com.wzdigit.mes.basic.dto.VendorDTO;
import com.wzdigit.wms.basic.client.Pager;
import com.wzdigit.wms.basic.client.PagerInfo;
import com.wzdigit.wms.basic.client.response.Result;
import com.wzdigit.wms.basic.client.response.basic.LocationResponse;
import com.wzdigit.wms.basic.domain.basic.Location;
import com.wzdigit.wms.basic.domain.basic.Sku;
import com.wzdigit.wms.basic.domain.inventory.Goods;
import com.wzdigit.wms.basic.domain.inventory.Lotno;
import com.wzdigit.wms.basic.enums.GoodsStatusEnum;
import com.wzdigit.wms.basic.enums.inventory.count.dtl.InvDtlResultEnum;
import com.wzdigit.wms.basic.enums.inventory.count.dtl.InvDtlStatusEnum;
import com.wzdigit.wms.basic.enums.inventory.count.goods.InvIsExitEnum;
import com.wzdigit.wms.basic.enums.inventory.count.header.InvHeaderStatusEnum;
import com.wzdigit.wms.basic.mapper.core.basic.LocationMapper;
import com.wzdigit.wms.basic.mapper.core.basic.SkuMapper;
import com.wzdigit.wms.basic.mapper.core.inventory.GoodsMapper;
import com.wzdigit.wms.basic.service.code.LotnoService;
import com.wzdigit.wms.wms.domain.dto.inv.count.InvCountDtlGoodsResponse;
import com.wzdigit.wms.wms.domain.dto.inv.count.InvCountDtlRequest;
import com.wzdigit.wms.wms.domain.dto.inv.count.InvCountDtlResponse;
import com.wzdigit.wms.wms.domain.inv.count.InvCountDtl;
import com.wzdigit.wms.wms.domain.inv.count.InvCountDtlGoods;
import com.wzdigit.wms.wms.domain.inv.count.InvCountHeader;
import com.wzdigit.wms.wms.mapper.inv.count.InvCountDtlGoodsMapper;
import com.wzdigit.wms.wms.mapper.inv.count.InvCountDtlMapper;
import com.wzdigit.wms.wms.mapper.inv.count.InvCountHeaderMapper;
import lombok.extern.slf4j.Slf4j;
import net.dreamlu.mica.core.utils.BeanUtil;
import net.dreamlu.mica.core.utils.CollectionUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.bouncycastle.ocsp.RespID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class StockCountDtlGoodsService {



    @Reference(version = "${dubbo.consumers.basic.vendor.api:1.0.0}", check = false, timeout = 300000)
    private BasicVendorApi  basicVendorApi;

    @Autowired
    LocationMapper locationMapper;
    @Autowired
    InvCountHeaderMapper headerMapper ;

    @Autowired
    InvCountDtlMapper dtlMapper;
    @Autowired
    GoodsMapper goodsMapper ;
    @Autowired
    InvCountDtlGoodsMapper invCountDtlGoodsMapper;
    @Autowired
    InvCountDtlMapper invCountDtlMapper;
    @Autowired
    SkuMapper skuMapper ;
    @Autowired
    LotnoService lotnoService;


    public PagerInfo<List<InvCountDtlResponse>> selectDetail(InvCountDtlRequest detailRequest, Pager pager) {
        Page<?> page = PageHelper.offsetPage(pager.getSkipCount(), pager.getMaxResultCount());
        PagerInfo<List<InvCountDtlResponse>> pagerInfo = new PagerInfo<>();
        List<InvCountDtlResponse> list = null;//dtlMapper.selectCount(detailRequest);
        pagerInfo.setTotalCount(page.getTotal());
        pagerInfo.setItems(list);
        return pagerInfo;

    }
    @Transactional
    public Result<InvCountDtlResponse> saveMatnrScan(String sn, String skuCode,Boolean isFirst,BigDecimal headerId,String loginName) {

        Result<InvCountDtlResponse> result = new Result<>();
        InvCountHeader invCountHeader = headerMapper.selectById(headerId);
        //2 查询sn有没有在盘点sn明细里面
        List<InvCountDtlGoods> invCountDtlGoodsList = invCountDtlGoodsMapper.selectSnByHeaderId(headerId,null,sn,null);
        InvCountDtlGoods invCountDtlGoods = invCountDtlGoodsList.size()==0?null:invCountDtlGoodsList.get(0);
        if (invCountDtlGoodsList==null||invCountDtlGoodsList.size()==0) {
            //查询goods表是否存在
            Goods goods = goodsMapper.selectBySn(sn);
            //新增盘盈必备条件
            if(goods==null||goods.getStatus()== GoodsStatusEnum.CREATE.code) {
                result.setCode(2);//定code 2为新增盘盈
                result.setFlag(false);
                result.setMessage("SN【"+sn+"】不存在于物料清单,是否新增盘盈?");
                return result;
            }else{
                Shift.fatal("当前SN在库存表中已经存在，并且不在当前盘点任务范围中");
            }
        }
        if (InvIsExitEnum.YES.code == invCountDtlGoods.getIsExist()) {
            Shift.fatal("该SN已经被盘点，请勿重复盘点");
        }
        //3 查询SN所在明细和料号是否对应
        //3.1 查询sn对应的任务明细
        InvCountDtl invCountDtl = invCountDtlMapper.selectById(invCountDtlGoods.getInvCountDtlId());


        //非新建或者盘点中
        if (invCountDtl.getStatus() != InvDtlStatusEnum.CREATE.code && invCountDtl.getStatus() != InvDtlStatusEnum.ING.code) {
            Shift.fatal("该SN物料对应盘点明细状态为【" + InvDtlStatusEnum.getEnumByCode(invCountDtl.getStatus()).getEnumName() + "】不符合盘点要求");
        }
        Sku sku = skuMapper.selectById(invCountDtl.getSkuId());
        if (skuCode.equals(sku.getSkuCode())) {
            //物料对应明细物料，保存SN数据
            invCountDtlGoods.setCountQty(invCountDtlGoods.getAccountQty());
            invCountDtlGoods.setIsExist(InvIsExitEnum.YES.code);
            invCountDtlGoods.setCountBy(loginName);
            invCountDtlGoods.setCountTime(new Date());
            invCountDtlGoods.setCountLoc(invCountDtlGoods.getAccountLoc());
            invCountDtlGoods.setResult(InvDtlResultEnum.NORMAL.code);
            invCountDtlGoodsMapper.updateById(invCountDtlGoods);
            //增加对应明细盘点的数量
            invCountDtl.setCountQty(invCountDtl.getCountQty().add(invCountDtlGoods.getAccountQty()));
            //更改盘点状态
            invCountDtl.setStatus(InvDtlStatusEnum.ING.code);
            invCountDtl.setModifyUser(loginName);
            invCountDtl.setModifyTime(new Date());
            invCountDtlMapper.updateById(invCountDtl);
            //更新表头状态
            invCountHeader.setStatus(isFirst? InvHeaderStatusEnum.ING_INV.code:InvHeaderStatusEnum.ING_REL_INV.code);
            invCountHeader.setModifyUser(loginName);
            invCountHeader.setModifyTime(new Date());
            headerMapper.updateById(invCountHeader);
        } else {
            Shift.fatal("SN对应编码" + sku.getSkuCode() + "和当前盘点物料不对应");
        }
        InvCountDtlResponse invCountDtlResponse = new InvCountDtlResponse();
        BeanUtil.copyNonNull(invCountDtl, invCountDtlResponse);
        invCountDtlResponse.setSnCountQty(invCountDtlGoods.getAccountQty());
        //查询库位编码
        if(invCountDtlResponse.getLocId()==null){
            invCountDtlResponse.setLocCode(StockCountDtlService.NULL_LOC);
        }else{
            Location location = locationMapper.selectById(invCountDtlResponse.getLocId());
            invCountDtlResponse.setLocCode(location.getLocCode());
        }
        result.setData(invCountDtlResponse);
        return result;

    }

    @Transactional
    public Result<InvCountDtlResponse> saveStockScan(String sn, String locCode,Boolean isFirst,BigDecimal headerId, String loginName) {
        Result<InvCountDtlResponse> result = new Result<>();
        InvCountHeader invCountHeader = headerMapper.selectById(headerId);
        //2 查询sn有没有在盘点sn明细里面
        List<InvCountDtlGoods> invCountDtlGoodsList = invCountDtlGoodsMapper.selectSnByHeaderId(headerId,null,sn,null);
        InvCountDtlGoods invCountDtlGoods = invCountDtlGoodsList.size()==0?null:invCountDtlGoodsList.get(0);
        if(invCountDtlGoods==null){
            Goods goods = goodsMapper.selectBySn(sn);
            //新增盘盈必备条件
            if(goods==null||goods.getStatus()== GoodsStatusEnum.CREATE.code) {
                result.setCode(2);//定code 2为新增盘盈
                result.setFlag(false);
                result.setMessage("SN【"+sn+"】不存在于物料清单,是否新增盘盈?");
                return result;
            }else{
                Shift.fatal("当前SN在库存表中已经存在，并且不在当前盘点任务范围中");
            }
        }
        if(InvIsExitEnum.YES.code==invCountDtlGoods.getIsExist()){
            Shift.fatal("该SN已经被盘点，请勿重复盘点");
        }
        //3 查询SN所在明细和料号是否对应
        //3.1 查询sn对应的任务明细
        InvCountDtl invCountDtl = invCountDtlMapper.selectById(invCountDtlGoods.getInvCountDtlId());
        //非新建或者盘点中
        if(invCountDtl.getStatus()!= InvDtlStatusEnum.CREATE.code&&invCountDtl.getStatus()!=InvDtlStatusEnum.ING.code){
            Shift.fatal("该SN物料对应盘点明细状态为【"+InvDtlStatusEnum.getEnumByCode(invCountDtl.getStatus()).getEnumName()+"】不符合盘点要求");
        }

        Sku sku = skuMapper.selectById(invCountDtl.getSkuId());
        LocationResponse locationResponse = locationMapper.selectOneByLocId(invCountDtl.getLocId());

        if(locCode.equals(locationResponse.getLocCode())){
            //物料对应明细物料，保存SN数据
            invCountDtlGoods.setCountQty(invCountDtlGoods.getAccountQty());
            invCountDtlGoods.setCountLoc(invCountDtlGoods.getAccountLoc());
            invCountDtlGoods.setResult(InvDtlResultEnum.NORMAL.code);
            invCountDtlGoods.setIsExist(InvIsExitEnum.YES.code);
            invCountDtlGoods.setCountBy(loginName);
            invCountDtlGoods.setCountTime(new Date());

            invCountDtlGoodsMapper.updateById(invCountDtlGoods);
            //增加对应明细盘点的数量
            invCountDtl.setCountQty(invCountDtl.getCountQty().add(invCountDtlGoods.getAccountQty()));
            //更改盘点状态
            invCountDtl.setStatus(InvDtlStatusEnum.ING.code);
            invCountDtl.setModifyUser(loginName);
            invCountDtl.setModifyTime(new Date());
            invCountDtlMapper.updateById(invCountDtl);
            //更新表头状态
            invCountHeader.setStatus(isFirst? InvHeaderStatusEnum.ING_INV.code:InvHeaderStatusEnum.ING_REL_INV.code);
            //invCountHeader.setCountBy(loginName);
            invCountHeader.setModifyUser(loginName);
            invCountHeader.setModifyTime(new Date());
            headerMapper.updateById(invCountHeader);
        }else{
            Shift.fatal("SN【"+sn+"】账面库位【"+locationResponse.getLocCode()+"】和当前盘点库位不一致，请将物料移动到原库位");
        }
        InvCountDtlResponse invCountDtlResponse = new InvCountDtlResponse();
        BeanUtil.copyNonNull(invCountDtl,invCountDtlResponse);
        invCountDtlResponse.setSnCountQty(invCountDtlGoods.getAccountQty()); //设置当前条码盘点数量
        result.setData(invCountDtlResponse);
        //查询库位编码
        if(invCountDtlResponse.getLocId()==null){
            invCountDtlResponse.setLocCode(StockCountDtlService.NULL_LOC);
        }else{
            Location location = locationMapper.selectById(invCountDtlResponse.getLocId());
            invCountDtlResponse.setLocCode(location.getLocCode());

        }
        return  result ;
    }



    @Transactional
    public Result changeQty(String sn, BigDecimal qty,BigDecimal headerId, String loginName) {
        //2 查询sn有没有在盘点sn明细里面

        List<InvCountDtlGoods> invCountDtlGoodsList = invCountDtlGoodsMapper.selectSnByHeaderId(headerId,null,sn,null);
        InvCountDtlGoods invCountDtlGoods = invCountDtlGoodsList.size()==0?null:invCountDtlGoodsList.get(0);
        //查询对应的明细
        if(invCountDtlGoods==null){
            Shift.fatal("未找到对应的SN任务");
        }
        BigDecimal addQty = qty.subtract(invCountDtlGoods.getCountQty());

        //修改实盘数量
        if(qty.compareTo(invCountDtlGoods.getAccountQty())==-1){
            invCountDtlGoods.setResult(InvDtlResultEnum.LOSS.code);
        }else if(qty.compareTo(invCountDtlGoods.getAccountQty())==1){
            invCountDtlGoods.setResult(InvDtlResultEnum.PROFIT.code);
        }else{
            invCountDtlGoods.setResult(InvDtlResultEnum.NORMAL.code);
        }
        invCountDtlGoods.setCountQty(qty);
        invCountDtlGoods.setCountTime(new Date());
        invCountDtlGoods.setCountBy(loginName);
        invCountDtlGoodsMapper.updateById(invCountDtlGoods);
        //查询SN对应的任务
        InvCountDtl invCountDtl = invCountDtlMapper.selectById(invCountDtlGoods.getInvCountDtlId());
        if(invCountDtl.getStatus()==InvDtlStatusEnum.FINISH.code){
            Shift.fatal("SN对应的盘点任务已经提交结果，无法变更！");
        }

        //修改任务明细的实盘数量
        invCountDtlMapper.updateCountQtyById(addQty,invCountDtl.getInvCountDtlId(),loginName);
        invCountDtl.setCountQty(invCountDtl.getCountQty().add(qty).subtract(invCountDtlGoods.getCountQty()));
        return  new Result();
    }


    public List<InvCountDtlGoodsResponse> list(BigDecimal dtlId) {
         //查询
        InvCountDtl invCountDtl = dtlMapper.selectById(dtlId);
        Sku sku = skuMapper.selectById(invCountDtl.getSkuId());
        VendorDTO vender = basicVendorApi.getVendorById(invCountDtl.getVendor());
        QueryWrapper<InvCountDtlGoods> wrapper = new QueryWrapper<>();
        wrapper.setEntity(new InvCountDtlGoods().setInvCountDtlId(dtlId));
        List<InvCountDtlGoods> invCountDtlGoods = invCountDtlGoodsMapper.selectList(wrapper);
        List<InvCountDtlGoodsResponse> list = new ArrayList<>();
        for(InvCountDtlGoods item : invCountDtlGoods){
            InvCountDtlGoodsResponse response = new InvCountDtlGoodsResponse();
            BeanUtil.copyNonNull(item,response);
            response.setSkuCode(sku.getSkuCode());
            response.setLotNo(invCountDtl.getLotno());
            //查询批次属性
            Lotno lotno = null;
            if(invCountDtl.getLotno()!=null) {
                lotno = lotnoService.selectByLotno(invCountDtl.getLotno());
                if(lotno!=null){
                    response.setLotAttr(lotno.getLotAttr());
                }
            }

            //查询账面库位
            if(item.getAccountLoc()==null){
                response.setAccountLocCode(StockCountDtlService.NULL_LOC);
            }else{
                Location location = locationMapper.selectById(item.getAccountLoc());
                response.setAccountLocCode(location.getLocCode());
            }
            //查询实盘库位
            if(item.getCountLoc()==null){
                response.setCountLocCode(StockCountDtlService.NULL_LOC);
            }else{
                Location location = locationMapper.selectById(item.getCountLoc());
                response.setCountLocCode(location.getLocCode());
            }

            response.setFactory(invCountDtl.getFactory());
            response.setInvAttr(invCountDtl.getInvAttr());
            response.setQaStatus(invCountDtl.getQaStatus()+"");
            response.setVendorName(vender.getVendorName());
            list.add(response);
        }
        return  list;
    }



}
